'''
项目名称：数据采集器
固件版本信息:V3.0.1
对应软件版:V3.0
日期:2025-10-25
作者:Hoyt
'''

import utime as time
import rtc
import app_config
import hmi_drv
import sensor_interface
import m485Drv
import tfcard
import app_relay
# import yun_network
import power
import led_drv

# import sleep_mode



sensor_instan = None
rtc_instan = None
collect_flag = 0
max_wait_time = 1    # 单位分钟

# 读取传感器数据回调
def collected_data_handler(sensor_name=None,**kwargs):
    global sensor_instan
    if not sensor_instan:
        print('sensor is not init')
        return []
    return sensor_instan.read_sensor(sensor_name, **kwargs)
# 返回上位机时间 
def rtc_handler(year=None, month=None, day=None, hour=None, minute=None, second=None):
    global rtc_instan
    # 如果传入了参数，则设置时间
    if year is not None:
        rtc_instan.set_time(year,month,day,hour,minute,second)  # 系统时间
        rtc_instan.rtc_set_time(year,month,day,hour,minute,second)  # 模块RTC时间
    d = rtc_instan.getRtcTime()
    # print("current RTC time:",d)
    return d

def main():
# 变量
    global sensor_instan,max_wait_time
    global rtc_instan,collect_flag
    relay_lead_seconds = 3
# config配置初始化
    app_config.config_init()
    soil_sensors = app_config.read_sensor_schema('soil')
# 网络注册
    # yun_network.connect_network()
    led_drv.led_on("LED2")
# 初始化系统rtc
    rtc_instan = rtc.SysRtc()
# 创建传感器实例

# 创建tf卡接口实例
    tf = tfcard.SetTfCard(rtc_instan)
# 创建串口通信实例
    uart_proj = hmi_drv.HmiDrver()
# 注册串口通信接收数据回调
    uart_proj.register_calback(collected_data_handler)
# 注册触摸屏RTC接口回调
    uart_proj.register_rtc_calback(rtc_handler)
# 注册tf卡接口回调
    uart_proj.register_tf_calback(tf)
# 获取串口屏RTC时间
    # uart_proj.ReadRTC()
# 创建传感器接口实例
    sensor_instan = sensor_interface.SensorInterface()
# 注册传感器参数数据
    #方式1：注册单个传感器
    # sensor_instan.register_sensor(soil =(rs485_modbus,'read_soil_sensor')) 
    # 方式2：注册多实例传感器（适合大量相同类型但参数不同的传感器）
    sensor_instan.register_sensor(
                soil={
                        "port": m485Drv,             
                        "method": soil_sensors['method'],     # 虚拟函数read_virtual_soil_sensor/实际函数read_soil_sensor
                        "instances": soil_sensors['instances']
                    }
                )
 
    last_collection_time = None
    last_next_time = None 
    
    # 进入低功耗
    # yun_network.set_flight_mode(1) # 1: 飞行模式 2：普通模式
    led_drv.led_off("LED2")
    # sleep_mode.sys_sleep(1)
    
# 主循环
    while True:
        # 读取方式1：读取所有传感器
        # data  = collected_data_handler()
        # 读取方式2：读取特定传感器
        # soil1_data = collected_data_handler('soil1')
        # 读取方式3：临时指定参数（覆盖注册时的参数）
        # 获取当前时间
        # 获取当前时间
        if uart_proj.get_collect_flag():
            # 直接从RTC获取时间字符串
            current_time_tuple = rtc_instan.sys_rtc()
            # 只在需要时计算下次采集时间
            if last_collection_time is None or current_time_tuple != last_collection_time:
                interval = uart_proj.get_interval()
                # 使用新的函数，直接传入时间字符串
                next_time, wait_seconds = rtc_instan.get_next_collection_time_with_time(int(interval))
                # next_time, wait_seconds = rtc_instan.get_next_collection_time_with_time(300)
                print("Wait seconds:", wait_seconds)
                # print("Next time: ", next_time)  # 调试信息
                # 判断是否到了采集时间（容忍2秒误差）
                if wait_seconds <= 7 and next_time != last_next_time:
                    # 低功耗模式
                    # sleep_mode.voltage_3v3(1)
                    # tf.mount_sd_card()
                    led_drv.led_on("LED1")
                    if wait_seconds > relay_lead_seconds:
                        # app_relay.relay_ctl(1,1)
                        time.sleep(wait_seconds - relay_lead_seconds)  # 等待到采集时间前2秒
                        app_relay.relay_ctl(1,1)
                        time.sleep(relay_lead_seconds)  #启继电器，开始为传感器供电 
                    else:
                        # 时间不足提前量：立刻供电，然后睡到采集时刻
                        app_relay.relay_ctl(1,1)
                        time.sleep(max(wait_seconds, 0))
                    # print("Starting data collection...")  # 调试信息
                    data = collected_data_handler()  
                    data_list = []
                    # print("TF data:",data)
                    power_votage = float(power.power_votage())
                    # 动态处理传感器数据，根据config.json配置
                    for instance in soil_sensors['instances']:
                        sensor_name = instance['name']
                        if sensor_name in data:
                            sensor_data = data[sensor_name]
                            # 添加传感器的所有参数值（通常是[0]湿度和[1]温度）
                            for i in range(len(sensor_data)):
                                data_list.append(sensor_data[i])
                    data_list.append(power_votage)
                    print(data_list)
                # 存储数据到TF卡
                    csv_header = app_config.read_headers_from_config()
                    tf.wirte_to_csv(csv_header,data_list) 
                     
                #  记录采集时间，避免重复采集
                    last_collection_time = current_time_tuple
                    last_next_time = next_time
                    # 采集完成后等待
                    time.sleep(0.5) 
                    app_relay.relay_ctl(1,0)
                    led_drv.led_off("LED1")
                    # 低功耗模式
                    # sleep_mode.voltage_3v3(0)
                else:
                    #动态等待时间
                    if wait_seconds > 7:
                        # 如果等待时间较长，分段睡眠
                        time.sleep(min(wait_seconds - 5, 60))  # 留60秒缓冲
                    else:
                        # 等待时间较短，精确睡眠
                        time.sleep(max(wait_seconds - 1, 0.5))  # 留1秒缓冲 
            else:
                # 短暂等待
                time.sleep(1)
        else:
            time.sleep(1)
            collect_flag += 1
            if collect_flag >= max_wait_time *60:
                collect_flag = 0
                uart_proj.set_collect_flag(True)
                collect_flag = 0
        

if __name__ == '__main__':
     main()
